package com.uvnos4j.matilda.system.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uvnos4j.matilda.commons.annotation.AppLog;
import com.uvnos4j.matilda.commons.dto.GridTable;
import com.uvnos4j.matilda.commons.dto.PageParam;
import com.uvnos4j.matilda.commons.dto.QueryParam;
import com.uvnos4j.matilda.commons.dto.Result;
import com.uvnos4j.matilda.commons.utils.RequestUtil;
import com.uvnos4j.matilda.commons.utils.TreeUtil;
import com.uvnos4j.matilda.system.domain.SysAcl;
import com.uvnos4j.matilda.system.domain.SysRole;
import com.uvnos4j.matilda.system.domain.SysUser;
import com.uvnos4j.matilda.system.service.SysAclService;
import com.uvnos4j.matilda.system.service.SysRoleService;
import com.uvnos4j.matilda.system.service.SysUserService;
import com.uvnos4j.matilda.system.vo.UserVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户 Controller
 * <p>
 * Description:用户 Controller
 * </p>
 *
 * @author Guo.wl
 * @version v1.0.0
 * @see com.uvnos4j.matilda.system.controller
 * @since 2020-08-31 23:26:56
 */
@Controller
@RequestMapping("/sys/user")
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysAclService sysAclService;

    @AppLog(title = "用户管理")
    @PreAuthorize("hasAuthority('sys:user')")
    @GetMapping("/list")
    public String list() {
        return "sys/userlist";
    }

    /**
     * 添加
     *
     * @param userVo vo对象
     * @return Result
     */
    @AppLog(title = "添加用户")
    @PreAuthorize("hasAuthority('sys:user:add')")
    @ResponseBody
    @PostMapping
    public Result add(@Valid UserVo userVo) {
        SysUser sysUser = userVo.buildModel(SysUser.class, false);
        boolean result = sysUserService.save(sysUser);
        if (result) {
            return Result.success("用户添加成功", sysUser.getId());
        }
        return Result.fail("用户添加失败");
    }

    /**
     * 修改
     *
     * @param userVo vo对象
     * @return Result
     */
    @AppLog(title = "修改用户")
    @PreAuthorize("hasAuthority('sys:user:update')")
    @ResponseBody
    @PutMapping
    public Result update(@Valid UserVo userVo) {
        SysUser sysUser = userVo.buildModel(SysUser.class, true);
        boolean result = sysUserService.updateById(sysUser);
        if (result) {
            return Result.success("用户修改成功", sysUser.getId());
        }
        return Result.fail("用户修改失败");
    }

    /**
     * 删除
     *
     * @param idList idList
     * @return Result
     */
    @AppLog(title = "删除用户")
    @PreAuthorize("hasAuthority('sys:user:del')")
    @ResponseBody
    @DeleteMapping
    public Result delete(@RequestParam("ids") List<Long> idList) {
        boolean result = sysUserService.removeByIds(idList);
        if (result) {
            return Result.success("用户删除成功,删除[" + idList.size() + "]条记录");
        }
        return Result.fail("用户删除失败");
    }

    /**
     * 分页查询
     *
     * @return Result
     */
    @PreAuthorize("hasAuthority('sys:user')")
    @ResponseBody
    @GetMapping()
    public Result findPage() {
        // 组装分页信息
        PageParam pageParam = RequestUtil.packagePageParamByNumAndSize("page", "rows");
        // 组装排序信息
        String orderBy = RequestUtil.packageOrderBy("sort", "order", true);
        // 得到所有的查询参数，注意也包括分页信息和排序信息
        QueryParam param = RequestUtil.getQueryParam();

        IPage<SysUser> page = sysUserService.findPage(param, pageParam, orderBy);
        GridTable<SysUser> table = new GridTable<>(page.getTotal(), page.getRecords());

        return Result.success(table);
    }

    /**
     * 导出
     *
     * @return Result
     */
    @AppLog(title = "导出用户")
    @PreAuthorize("hasAuthority('sys:user')")
    @ResponseBody
    @PostMapping("/export")
    public Result export() {
        // 构建分页信息
        PageParam pageParam = PageParam.buildByNumAndSize(1, Integer.MAX_VALUE);
        // 组装排序信息
        String orderBy = RequestUtil.packageOrderBy("sort", "order", true);
        // 得到所有的查询参数，注意也包括分页信息和排序信息
        QueryParam param = RequestUtil.getQueryParam();

        String filename = param.getStringValue("filename");
        String fileDest = RequestUtil.getDownloadPath() + filename;

        sysUserService.export(param, pageParam, orderBy, fileDest);

        return Result.success("文件正在下载，请稍后……", fileDest);
    }

    /**
     * 用户密码重置[管理员角色]
     *
     * @param idList 用户id集合
     * @return 操作结果
     */
    @AppLog(title = "用户密码重置")
    @PreAuthorize("hasAuthority('sys:user:resetPwd')")
    @ResponseBody
    @RequestMapping(value = "/resetPassword", method = RequestMethod.POST)
    public Result resetPassword(@RequestParam("ids") List<Long> idList) {
        boolean result = sysUserService.resetPassword(idList);
        if (result) {
            return Result.success("用户密码重置成功,影响[" + idList.size() + "]条记录");
        }
        return Result.fail("用户密码重置失败");
    }

    /**
     * 修改密码[当前登录用户]
     * PreAuthorize 说明:登录进来就有权限修改自己密码
     *
     * @param password    旧密码
     * @param newPassword 新密码
     * @return 操作结果
     */
    @AppLog(title = "修改密码")
    @ResponseBody
    @RequestMapping(value = "/updatePassword", method = RequestMethod.POST)
    public Result updatePassword(@RequestParam String password, @RequestParam String newPassword) {
        boolean result = sysUserService.updatePassword(password, newPassword);
        if (result) {
            return Result.success("用户密码修改成功");
        }
        return Result.fail("用户密码修改失败");
    }

    /**
     * 查询用户关联的角色和权限
     *
     * @param userId userId
     * @return 用户关联的角色和权限信息
     */
    @PreAuthorize("hasAuthority('sys:user')")
    @ResponseBody
    @GetMapping("/findRoleAndAcl")
    public Result findRoleAndAcl(@RequestParam Long userId) {
        List<SysRole> roleList = sysRoleService.findByUserId(userId);
        List<SysAcl> aclList = sysAclService.findByUserId(userId);
        Map<String, Object> data = new HashMap<>(16);
        data.put("roleList", roleList);
        data.put("aclTree", TreeUtil.bulidTree(aclList));
        return Result.success(data);
    }

}